library(tidyverse)
library(gapminder)Clase 15: DPLYR, Factores, Coerce, Recycle, NA’s, tidyr
Parte 1: Trabajando con Múltiples Conjuntos de Datos
Cargar Librerías
Cargar Conjuntos de Datos
df_gapminder_csv <- read.csv('https://raw.githubusercontent.com/javendaXgh/datos/refs/heads/master/gapminder.csv')%>%
select(-X)%>%
as_tibble()
df_gapminder <- gapminder
df_gastosaludmundial <- read.csv('https://raw.githubusercontent.com/UCVeconomia2024-2/scripts/refs/heads/main/data_in/clase_12/IHME/IHME_HEALTH_SPENDING_1995_2021/IHME_HEALTH_SPENDING_1995_2021_Y2024M07D23.CSV')
# info sobre este conjunto de datos disponible en
#https://ghdx.healthdata.org/record/ihme-data/global-health-spending-1995-2021
#https://github.com/UCVeconomia2024-2/scripts/tree/main/data_in/clase_12/IHME
df_ventas <- read.csv('https://raw.githubusercontent.com/UCVeconomia2024-2/scripts/refs/heads/main/data_in/df_ventas.csv')DF Global Health Data Exchange.
Revisar contenido a forma de hacer un pre EDA (Exploratory Data Analysis)
dim(df_gastosaludmundial)[1] 5832 84
names(df_gastosaludmundial) [1] "location_id" "location_name" "iso3"
[4] "level" "year" "the_total_mean"
[7] "the_total_lower" "the_total_upper" "the_total_ppp_mean"
[10] "the_total_ppp_lower" "the_total_ppp_upper" "ghes_total_mean"
[13] "ghes_total_lower" "ghes_total_upper" "ghes_total_ppp_mean"
[16] "ghes_total_ppp_lower" "ghes_total_ppp_upper" "ppp_total_mean"
[19] "ppp_total_lower" "ppp_total_upper" "ppp_total_ppp_mean"
[22] "ppp_total_ppp_lower" "ppp_total_ppp_upper" "oop_total_mean"
[25] "oop_total_lower" "oop_total_upper" "oop_total_ppp_mean"
[28] "oop_total_ppp_lower" "oop_total_ppp_upper" "dah_total_mean"
[31] "dah_total_ppp_mean" "the_per_cap_mean" "the_per_cap_lower"
[34] "the_per_cap_upper" "the_per_cap_ppp_mean" "the_per_cap_ppp_lower"
[37] "the_per_cap_ppp_upper" "ghes_per_cap_mean" "ghes_per_cap_lower"
[40] "ghes_per_cap_upper" "ghes_per_cap_ppp_mean" "ghes_per_cap_ppp_lower"
[43] "ghes_per_cap_ppp_upper" "ppp_per_cap_mean" "ppp_per_cap_lower"
[46] "ppp_per_cap_upper" "ppp_per_cap_ppp_mean" "ppp_per_cap_ppp_lower"
[49] "ppp_per_cap_ppp_upper" "oop_per_cap_mean" "oop_per_cap_lower"
[52] "oop_per_cap_upper" "oop_per_cap_ppp_mean" "oop_per_cap_ppp_lower"
[55] "oop_per_cap_ppp_upper" "dah_per_cap_mean" "dah_per_cap_ppp_mean"
[58] "ghes_per_the_mean" "ghes_per_the_lower" "ghes_per_the_upper"
[61] "ppp_per_the_mean" "ppp_per_the_lower" "ppp_per_the_upper"
[64] "oop_per_the_mean" "oop_per_the_lower" "oop_per_the_upper"
[67] "dah_per_the_mean" "dah_per_the_lower" "dah_per_the_upper"
[70] "the_per_gdp_mean" "the_per_gdp_lower" "the_per_gdp_upper"
[73] "ghes_per_gdp_mean" "ghes_per_gdp_lower" "ghes_per_gdp_upper"
[76] "ppp_per_gdp_mean" "ppp_per_gdp_lower" "ppp_per_gdp_upper"
[79] "oop_per_gdp_mean" "oop_per_gdp_lower" "oop_per_gdp_upper"
[82] "dah_per_gdp_mean" "dah_per_gdp_lower" "dah_per_gdp_upper"
summary(df_gastosaludmundial[,1:10]) location_id location_name iso3 level
Min. : 1.00 Length:5832 Length:5832 Length:5832
1st Qu.: 62.75 Class :character Class :character Class :character
Median : 124.00 Mode :character Mode :character Mode :character
Mean : 957.29
3rd Qu.: 183.25
Max. :44578.00
year the_total_mean the_total_lower the_total_upper
Min. :1995 Min. :3.730e+02 Min. :2.660e+02 Min. :5.030e+02
1st Qu.:2001 1st Qu.:2.811e+05 1st Qu.:2.497e+05 1st Qu.:3.153e+05
Median :2008 Median :1.530e+06 Median :1.389e+06 Median :1.666e+06
Mean :2008 Mean :1.226e+08 Mean :1.202e+08 Mean :1.251e+08
3rd Qu.:2015 3rd Qu.:1.214e+07 3rd Qu.:1.144e+07 3rd Qu.:1.296e+07
Max. :2021 Max. :1.016e+10 Max. :1.006e+10 Max. :1.027e+10
the_total_ppp_mean the_total_ppp_lower
Min. :8.000e+00 Min. :7.000e+00
1st Qu.:5.599e+05 1st Qu.:4.680e+05
Median :3.543e+06 Median :3.242e+06
Mean :1.660e+08 Mean :1.620e+08
3rd Qu.:2.599e+07 3rd Qu.:2.394e+07
Max. :1.401e+10 Max. :1.389e+10
str(df_gastosaludmundial[,1:10])'data.frame': 5832 obs. of 10 variables:
$ location_id : int 1 1 1 1 1 1 1 1 1 1 ...
$ location_name : chr "Global" "Global" "Global" "Global" ...
$ iso3 : chr "G" "G" "G" "G" ...
$ level : chr "Global" "Global" "Global" "Global" ...
$ year : int 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 ...
$ the_total_mean : num 3.80e+09 3.91e+09 4.06e+09 4.22e+09 4.36e+09 ...
$ the_total_lower : num 3.57e+09 3.78e+09 3.96e+09 4.13e+09 4.28e+09 ...
$ the_total_upper : num 4.02e+09 4.04e+09 4.16e+09 4.31e+09 4.45e+09 ...
$ the_total_ppp_mean : num 5.12e+09 5.28e+09 5.48e+09 5.68e+09 5.85e+09 ...
$ the_total_ppp_lower: num 4.79e+09 5.05e+09 5.31e+09 5.53e+09 5.71e+09 ...
Listado de Países con Datos
Vamos a evaluar cuáles países disponen de datos en esta df:
unique(df_gastosaludmundial$location_name) [1] "Global"
[2] "High income"
[3] "Low income"
[4] "Lower-middle income"
[5] "Upper-middle income"
[6] "Central Europe, Eastern Europe, and Central Asia"
[7] "High-income"
[8] "Latin America and Caribbean"
[9] "North Africa and Middle East"
[10] "South Asia"
[11] "Southeast Asia, East Asia, and Oceania"
[12] "Sub-Saharan Africa"
[13] "Afghanistan"
[14] "Albania"
[15] "Algeria"
[16] "American Samoa"
[17] "Andorra"
[18] "Angola"
[19] "Antigua and Barbuda"
[20] "Argentina"
[21] "Armenia"
[22] "Australia"
[23] "Austria"
[24] "Azerbaijan"
[25] "Bahamas"
[26] "Bahrain"
[27] "Bangladesh"
[28] "Barbados"
[29] "Belarus"
[30] "Belgium"
[31] "Belize"
[32] "Benin"
[33] "Bermuda"
[34] "Bhutan"
[35] "Bolivia (Plurinational State of)"
[36] "Bosnia and Herzegovina"
[37] "Botswana"
[38] "Brazil"
[39] "Brunei Darussalam"
[40] "Bulgaria"
[41] "Burkina Faso"
[42] "Burundi"
[43] "Cabo Verde"
[44] "Cambodia"
[45] "Cameroon"
[46] "Canada"
[47] "Central African Republic"
[48] "Chad"
[49] "Chile"
[50] "China"
[51] "Colombia"
[52] "Comoros"
[53] "Congo"
[54] "Cook Islands"
[55] "Costa Rica"
[56] "Croatia"
[57] "Cuba"
[58] "Cyprus"
[59] "Czechia"
[60] "Côte d'Ivoire"
[61] "Democratic People's Republic of Korea"
[62] "Democratic Republic of the Congo"
[63] "Denmark"
[64] "Djibouti"
[65] "Dominica"
[66] "Dominican Republic"
[67] "Ecuador"
[68] "Egypt"
[69] "El Salvador"
[70] "Equatorial Guinea"
[71] "Eritrea"
[72] "Estonia"
[73] "Eswatini"
[74] "Ethiopia"
[75] "Fiji"
[76] "Finland"
[77] "France"
[78] "Gabon"
[79] "Gambia"
[80] "Georgia"
[81] "Germany"
[82] "Ghana"
[83] "Greece"
[84] "Greenland"
[85] "Grenada"
[86] "Guam"
[87] "Guatemala"
[88] "Guinea"
[89] "Guinea-Bissau"
[90] "Guyana"
[91] "Haiti"
[92] "Honduras"
[93] "Hungary"
[94] "Iceland"
[95] "India"
[96] "Indonesia"
[97] "Iran (Islamic Republic of)"
[98] "Iraq"
[99] "Ireland"
[100] "Israel"
[101] "Italy"
[102] "Jamaica"
[103] "Japan"
[104] "Jordan"
[105] "Kazakhstan"
[106] "Kenya"
[107] "Kiribati"
[108] "Kuwait"
[109] "Kyrgyzstan"
[110] "Lao People's Democratic Republic"
[111] "Latvia"
[112] "Lebanon"
[113] "Lesotho"
[114] "Liberia"
[115] "Libya"
[116] "Lithuania"
[117] "Luxembourg"
[118] "Madagascar"
[119] "Malawi"
[120] "Malaysia"
[121] "Maldives"
[122] "Mali"
[123] "Malta"
[124] "Marshall Islands"
[125] "Mauritania"
[126] "Mauritius"
[127] "Mexico"
[128] "Micronesia (Federated States of)"
[129] "Monaco"
[130] "Mongolia"
[131] "Montenegro"
[132] "Morocco"
[133] "Mozambique"
[134] "Myanmar"
[135] "Namibia"
[136] "Nauru"
[137] "Nepal"
[138] "Netherlands"
[139] "New Zealand"
[140] "Nicaragua"
[141] "Niger"
[142] "Nigeria"
[143] "Niue"
[144] "North Macedonia"
[145] "Northern Mariana Islands"
[146] "Norway"
[147] "Oman"
[148] "Pakistan"
[149] "Palau"
[150] "Palestine"
[151] "Panama"
[152] "Papua New Guinea"
[153] "Paraguay"
[154] "Peru"
[155] "Philippines"
[156] "Poland"
[157] "Portugal"
[158] "Puerto Rico"
[159] "Qatar"
[160] "Republic of Korea"
[161] "Republic of Moldova"
[162] "Romania"
[163] "Russian Federation"
[164] "Rwanda"
[165] "Saint Kitts and Nevis"
[166] "Saint Lucia"
[167] "Saint Vincent and the Grenadines"
[168] "Samoa"
[169] "San Marino"
[170] "Sao Tome and Principe"
[171] "Saudi Arabia"
[172] "Senegal"
[173] "Serbia"
[174] "Seychelles"
[175] "Sierra Leone"
[176] "Singapore"
[177] "Slovakia"
[178] "Slovenia"
[179] "Solomon Islands"
[180] "Somalia"
[181] "South Africa"
[182] "South Sudan"
[183] "Spain"
[184] "Sri Lanka"
[185] "Sudan"
[186] "Suriname"
[187] "Sweden"
[188] "Switzerland"
[189] "Syrian Arab Republic"
[190] "Taiwan"
[191] "Tajikistan"
[192] "Thailand"
[193] "Timor-Leste"
[194] "Togo"
[195] "Tokelau"
[196] "Tonga"
[197] "Trinidad and Tobago"
[198] "Tunisia"
[199] "Turkmenistan"
[200] "Tuvalu"
[201] "Türkiye"
[202] "Uganda"
[203] "Ukraine"
[204] "United Arab Emirates"
[205] "United Kingdom"
[206] "United Republic of Tanzania"
[207] "United States Virgin Islands"
[208] "United States of America"
[209] "Uruguay"
[210] "Uzbekistan"
[211] "Vanuatu"
[212] "Venezuela (Bolivarian Republic of)"
[213] "Viet Nam"
[214] "Yemen"
[215] "Zambia"
[216] "Zimbabwe"
Al trabajar con conjuntos de datos de este estilo es recomendable leer la documentación que les acompaña para tener nociones sobre cuáles son los datos representados y la metodología usada para el levantamiento de los mismos.
https://ghdx.healthdata.org/record/ihme-data/global-health-spending-1995-2021
https://github.com/UCVeconomia2024-2/scripts/tree/main/data_in/clase_12/IHME
Listado de Países América
df_paises_america <- df_gapminder_csv%>%
filter(continent=='Americas')crear df con valores duplicados uniendo dos df’s
df_paises_america2 <- bind_rows(df_paises_america,
df_paises_america%>%
sample_n(30)
)%>%
arrange(country, year)En la DF creada df_paises_america2 existen valores duplicados a los fines de crear un ejemplo de una DF con filas duplicadas
df_paises_america2%>%
print(n=30) # presencia de valores duplicados# A tibble: 330 × 6
country continent year lifeExp pop gdpPercap
<chr> <chr> <int> <dbl> <int> <dbl>
1 Argentina Americas 1952 62.5 17876956 5911.
2 Argentina Americas 1957 64.4 19610538 6857.
3 Argentina Americas 1957 64.4 19610538 6857.
4 Argentina Americas 1962 65.1 21283783 7133.
5 Argentina Americas 1967 65.6 22934225 8053.
6 Argentina Americas 1972 67.1 24779799 9443.
7 Argentina Americas 1977 68.5 26983828 10079.
8 Argentina Americas 1982 69.9 29341374 8998.
9 Argentina Americas 1987 70.8 31620918 9140.
10 Argentina Americas 1987 70.8 31620918 9140.
11 Argentina Americas 1992 71.9 33958947 9308.
12 Argentina Americas 1997 73.3 36203463 10967.
13 Argentina Americas 2002 74.3 38331121 8798.
14 Argentina Americas 2007 75.3 40301927 12779.
15 Bolivia Americas 1952 40.4 2883315 2677.
16 Bolivia Americas 1952 40.4 2883315 2677.
17 Bolivia Americas 1957 41.9 3211738 2128.
18 Bolivia Americas 1962 43.4 3593918 2181.
19 Bolivia Americas 1967 45.0 4040665 2587.
20 Bolivia Americas 1972 46.7 4565872 2980.
21 Bolivia Americas 1977 50.0 5079716 3548.
22 Bolivia Americas 1982 53.9 5642224 3157.
23 Bolivia Americas 1987 57.3 6156369 2754.
24 Bolivia Americas 1992 60.0 6893451 2962.
25 Bolivia Americas 1997 62.0 7693188 3326.
26 Bolivia Americas 2002 63.9 8445134 3413.
27 Bolivia Americas 2007 65.6 9119152 3822.
28 Bolivia Americas 2007 65.6 9119152 3822.
29 Brazil Americas 1952 50.9 56602560 2109.
30 Brazil Americas 1957 53.3 65551171 2487.
# ℹ 300 more rows
dim(df_paises_america)[1] 300 6
dim(df_paises_america2) # se incrementa por la presencia de valores duplicados[1] 330 6
Remoción de filas duplicadas:
df_paises_america_limpio <- df_paises_america2%>%
filter(continent=='Americas')%>%
distinct(country, lifeExp) #, .keep_all=TRUE
dim(df_paises_america_limpio)[1] 300 2
str(df_paises_america_limpio)tibble [300 × 2] (S3: tbl_df/tbl/data.frame)
$ country: chr [1:300] "Argentina" "Argentina" "Argentina" "Argentina" ...
$ lifeExp: num [1:300] 62.5 64.4 65.1 65.6 67.1 ...
df_paises_america_limpio# A tibble: 300 × 2
country lifeExp
<chr> <dbl>
1 Argentina 62.5
2 Argentina 64.4
3 Argentina 65.1
4 Argentina 65.6
5 Argentina 67.1
6 Argentina 68.5
7 Argentina 69.9
8 Argentina 70.8
9 Argentina 71.9
10 Argentina 73.3
# ℹ 290 more rows
Se están removiendo con base en la repetición de dos atributos por fila, pero pudieran ser más o menos los atributos a evaluar si se repiten implicando que la repetición puede ser evaluada parcial o totalmente
Remover filas duplicadas conservando todos los atributos
df_paises_america_limpio <- df_paises_america2%>%
filter(continent=='Americas')%>%
distinct(country, lifeExp, .keep_all=TRUE)
dim(df_paises_america_limpio)[1] 300 6
str(df_paises_america_limpio)tibble [300 × 6] (S3: tbl_df/tbl/data.frame)
$ country : chr [1:300] "Argentina" "Argentina" "Argentina" "Argentina" ...
$ continent: chr [1:300] "Americas" "Americas" "Americas" "Americas" ...
$ year : int [1:300] 1952 1957 1962 1967 1972 1977 1982 1987 1992 1997 ...
$ lifeExp : num [1:300] 62.5 64.4 65.1 65.6 67.1 ...
$ pop : int [1:300] 17876956 19610538 21283783 22934225 24779799 26983828 29341374 31620918 33958947 36203463 ...
$ gdpPercap: num [1:300] 5911 6857 7133 8053 9443 ...
df_paises_america_limpio# A tibble: 300 × 6
country continent year lifeExp pop gdpPercap
<chr> <chr> <int> <dbl> <int> <dbl>
1 Argentina Americas 1952 62.5 17876956 5911.
2 Argentina Americas 1957 64.4 19610538 6857.
3 Argentina Americas 1962 65.1 21283783 7133.
4 Argentina Americas 1967 65.6 22934225 8053.
5 Argentina Americas 1972 67.1 24779799 9443.
6 Argentina Americas 1977 68.5 26983828 10079.
7 Argentina Americas 1982 69.9 29341374 8998.
8 Argentina Americas 1987 70.8 31620918 9140.
9 Argentina Americas 1992 71.9 33958947 9308.
10 Argentina Americas 1997 73.3 36203463 10967.
# ℹ 290 more rows
Extracción países de América en Gapminder que estén en datos de GastosSaludMundial
La idea es poder extraer de la df de gastos en salud los países de América que están en Gapminder, suponiendo que queremos obtener otros datos que nos permitan enriquecer nuestro análisis sobre ambos conjuntos de datos y que estos se complementen.
Obtener listado de países de América según gapminder
paises_america <- df_gapminder_csv%>%
filter(continent=='Americas')%>%
select(country)%>%
distinct(country)%>%
pull(country)Notar uso de función pull para extraer los resultados en la estructura de un vector. Comparar sino se usará esa última línea, cuál sería el resultado.
Ahora se evalúa cuántos países únicos contiene el vector paises_america
length(paises_america) # cdad de paises[1] 25
Seleccionar columnas por aparición de una string en el nombre
Sabiendo que la palabra mean en inglés quiere decir promedio, a fines de ejemplificar el uso de la función select en conjunto con ends_with se propone el siguiente ejercicio:
df_gsm_mean <- df_gastosaludmundial%>%
filter(location_name %in% paises_america)%>%
select(location_name, year, ends_with('mean'))Sabiendo que la df en uso contiene 31, se propone seleccionar sólo los columnas que representen valores promedio y se hace aplicación conjunta de select y ends_with('mean'). También se seleccionan las columnas “location_name” y “year” ya que van a identificar dos atributos clave, como lo son el país y año que se representa en cada fila.
Igualmente, en el paso anterior se filtraron sólo los países de América que están contenidos en el vector paises_america.
Ahora inspeccionamos los nombres de los países de df_gsm_mean:
unique(df_gsm_mean$location_name) [1] "Argentina" "Brazil" "Canada"
[4] "Chile" "Colombia" "Costa Rica"
[7] "Cuba" "Dominican Republic" "Ecuador"
[10] "El Salvador" "Guatemala" "Haiti"
[13] "Honduras" "Jamaica" "Mexico"
[16] "Nicaragua" "Panama" "Paraguay"
[19] "Peru" "Puerto Rico" "Trinidad and Tobago"
[22] "Uruguay"
y en cuanto a las dimensiones de la df
dim(df_gsm_mean)[1] 594 31
Existe una diferencia, ya que hay 22 países en df_gsm_mean mientras que en paises_america hay 25, lo que implica que no se filtraron todos los países que se encuentran listados.
Esto se motiva en que los nombres difieren en escritura en las dos data frame´s.
Para evaluar un mecanismo alterno se va a crear una string con todos los nombres de los países con miras de detectar coincidencias no exactas sino parciales.
La función %in% aplica para detecciones de coincidencias exactas mientras que con str_detect hace la detección parcial.
El operador | sabemos que indica OR lo que quiere decir que o aparece Argentina o aparece Bolivia o …., etc.
string_paises <- paste0(paises_america,collapse = '|')
string_paises[1] "Argentina|Bolivia|Brazil|Canada|Chile|Colombia|Costa Rica|Cuba|Dominican Republic|Ecuador|El Salvador|Guatemala|Haiti|Honduras|Jamaica|Mexico|Nicaragua|Panama|Paraguay|Peru|Puerto Rico|Trinidad and Tobago|United States|Uruguay|Venezuela"
Nuevamente intentamos crear la df_gsm_mean:
df_gsm_mean <- df_gastosaludmundial%>%
filter(str_detect(location_name, string_paises))%>%
select(location_name,year, ends_with('mean'))
unique(df_gsm_mean$location_name) [1] "Argentina" "Bolivia (Plurinational State of)"
[3] "Brazil" "Canada"
[5] "Chile" "Colombia"
[7] "Costa Rica" "Cuba"
[9] "Dominican Republic" "Ecuador"
[11] "El Salvador" "Guatemala"
[13] "Haiti" "Honduras"
[15] "Jamaica" "Mexico"
[17] "Nicaragua" "Panama"
[19] "Paraguay" "Peru"
[21] "Puerto Rico" "Trinidad and Tobago"
[23] "United States Virgin Islands" "United States of America"
[25] "Uruguay" "Venezuela (Bolivarian Republic of)"
Para entender mejor el funcionamiento de str_detect consultamos la documentación.
library(stringr)
#?str_detect # consultar funciónHay que recordar que esta función está contenida en el paquete stringr que fue cargado previamente con la suite tidiverse.
Detección Países Faltantes
paises1 <- df_gastosaludmundial%>%
filter(location_name %in% paises_america)%>%
distinct(location_name)%>%
pull(location_name)
paises2 <- df_gastosaludmundial%>%
filter(str_detect(location_name, string_paises))%>%
distinct(location_name)%>%
pull(location_name)
paises2[paises2 %in% paises1] [1] "Argentina" "Brazil" "Canada"
[4] "Chile" "Colombia" "Costa Rica"
[7] "Cuba" "Dominican Republic" "Ecuador"
[10] "El Salvador" "Guatemala" "Haiti"
[13] "Honduras" "Jamaica" "Mexico"
[16] "Nicaragua" "Panama" "Paraguay"
[19] "Peru" "Puerto Rico" "Trinidad and Tobago"
[22] "Uruguay"
paises2[!paises2 %in% paises1][1] "Bolivia (Plurinational State of)" "United States Virgin Islands"
[3] "United States of America" "Venezuela (Bolivarian Republic of)"
Más adelante, en otra clase veremos cómo podemos juntar ambas data frames combinando los datos de una y otra por país haciendo joins de distinto tipo.
Parte 2: Factores
Estructura de datos que agrupa elementos en niveles o categorías. Son útiles cuando tienes variables categóricas, como género (hombre/mujer), tipo de producto (libro/revista) o cualquier otra variable que tenga un conjunto limitado de posibles valores.
library(forcats) # fue cargada previamente con tidyverse
paises_america2 <- df_gapminder%>%
filter(continent=='Americas')%>%
select(country)%>%
distinct(country)%>%
pull(country)
paises_america2 [1] Argentina Bolivia Brazil
[4] Canada Chile Colombia
[7] Costa Rica Cuba Dominican Republic
[10] Ecuador El Salvador Guatemala
[13] Haiti Honduras Jamaica
[16] Mexico Nicaragua Panama
[19] Paraguay Peru Puerto Rico
[22] Trinidad and Tobago United States Uruguay
[25] Venezuela
142 Levels: Afghanistan Albania Algeria Angola Argentina Australia ... Zimbabwe
La representación de los datos varía en formato a un vector de tipo caracter
levels(paises_america2) [1] "Afghanistan" "Albania"
[3] "Algeria" "Angola"
[5] "Argentina" "Australia"
[7] "Austria" "Bahrain"
[9] "Bangladesh" "Belgium"
[11] "Benin" "Bolivia"
[13] "Bosnia and Herzegovina" "Botswana"
[15] "Brazil" "Bulgaria"
[17] "Burkina Faso" "Burundi"
[19] "Cambodia" "Cameroon"
[21] "Canada" "Central African Republic"
[23] "Chad" "Chile"
[25] "China" "Colombia"
[27] "Comoros" "Congo, Dem. Rep."
[29] "Congo, Rep." "Costa Rica"
[31] "Cote d'Ivoire" "Croatia"
[33] "Cuba" "Czech Republic"
[35] "Denmark" "Djibouti"
[37] "Dominican Republic" "Ecuador"
[39] "Egypt" "El Salvador"
[41] "Equatorial Guinea" "Eritrea"
[43] "Ethiopia" "Finland"
[45] "France" "Gabon"
[47] "Gambia" "Germany"
[49] "Ghana" "Greece"
[51] "Guatemala" "Guinea"
[53] "Guinea-Bissau" "Haiti"
[55] "Honduras" "Hong Kong, China"
[57] "Hungary" "Iceland"
[59] "India" "Indonesia"
[61] "Iran" "Iraq"
[63] "Ireland" "Israel"
[65] "Italy" "Jamaica"
[67] "Japan" "Jordan"
[69] "Kenya" "Korea, Dem. Rep."
[71] "Korea, Rep." "Kuwait"
[73] "Lebanon" "Lesotho"
[75] "Liberia" "Libya"
[77] "Madagascar" "Malawi"
[79] "Malaysia" "Mali"
[81] "Mauritania" "Mauritius"
[83] "Mexico" "Mongolia"
[85] "Montenegro" "Morocco"
[87] "Mozambique" "Myanmar"
[89] "Namibia" "Nepal"
[91] "Netherlands" "New Zealand"
[93] "Nicaragua" "Niger"
[95] "Nigeria" "Norway"
[97] "Oman" "Pakistan"
[99] "Panama" "Paraguay"
[101] "Peru" "Philippines"
[103] "Poland" "Portugal"
[105] "Puerto Rico" "Reunion"
[107] "Romania" "Rwanda"
[109] "Sao Tome and Principe" "Saudi Arabia"
[111] "Senegal" "Serbia"
[113] "Sierra Leone" "Singapore"
[115] "Slovak Republic" "Slovenia"
[117] "Somalia" "South Africa"
[119] "Spain" "Sri Lanka"
[121] "Sudan" "Swaziland"
[123] "Sweden" "Switzerland"
[125] "Syria" "Taiwan"
[127] "Tanzania" "Thailand"
[129] "Togo" "Trinidad and Tobago"
[131] "Tunisia" "Turkey"
[133] "Uganda" "United Kingdom"
[135] "United States" "Uruguay"
[137] "Venezuela" "Vietnam"
[139] "West Bank and Gaza" "Yemen, Rep."
[141] "Zambia" "Zimbabwe"
levels(paises_america)NULL
Niveles
Contar elementos por nivel
fct_count(paises_america, sort = FALSE,
prop = FALSE)# A tibble: 25 × 2
f n
<fct> <int>
1 Argentina 1
2 Bolivia 1
3 Brazil 1
4 Canada 1
5 Chile 1
6 Colombia 1
7 Costa Rica 1
8 Cuba 1
9 Dominican Republic 1
10 Ecuador 1
# ℹ 15 more rows
No muestra los niveles que contienen NA´s
fct_drop(paises_america) [1] Argentina Bolivia Brazil
[4] Canada Chile Colombia
[7] Costa Rica Cuba Dominican Republic
[10] Ecuador El Salvador Guatemala
[13] Haiti Honduras Jamaica
[16] Mexico Nicaragua Panama
[19] Paraguay Peru Puerto Rico
[22] Trinidad and Tobago United States Uruguay
[25] Venezuela
25 Levels: Argentina Bolivia Brazil Canada Chile Colombia Costa Rica ... Venezuela
Se retoma al revisar contenido sobre los NA´s.
Vectores con factores
Crear un vector con factores
vector_factores <- factor(sample(1:10, 20, replace = TRUE),
levels = 1:11)
vector_factores [1] 7 8 8 5 7 6 6 1 7 10 2 3 4 7 3 10 5 7 7 9
Levels: 1 2 3 4 5 6 7 8 9 10 11
levels(vector_factores) [1] "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11"
Remover factores mediante RBase
Usando la familia de funciones as:
as.numeric(levels(vector_factores))[vector_factores] [1] 7 8 8 5 7 6 6 1 7 10 2 3 4 7 3 10 5 7 7 9
Remover factores mediante paquete varhandle
# install.packages('varhandle')
library(varhandle)
unfactor(vector_factores) [1] 7 8 8 5 7 6 6 1 7 10 2 3 4 7 3 10 5 7 7 9
Versión factor categorías
Crear un vector con factores
categorias <- c('muy bajo','bajo','medio','alto','muy alto')
vector_fact_categorias <- factor(sample(categorias, 30, replace = TRUE))
vector_fact_categorias [1] muy alto medio bajo alto muy alto bajo medio muy bajo
[9] alto muy alto muy alto bajo bajo muy bajo medio muy bajo
[17] muy bajo muy alto bajo medio muy alto alto muy alto muy alto
[25] medio bajo bajo bajo muy bajo muy alto
Levels: alto bajo medio muy alto muy bajo
Remover factores mediante RBase
as.character(levels(vector_fact_categorias))[vector_fact_categorias] [1] "muy alto" "medio" "bajo" "alto" "muy alto" "bajo"
[7] "medio" "muy bajo" "alto" "muy alto" "muy alto" "bajo"
[13] "bajo" "muy bajo" "medio" "muy bajo" "muy bajo" "muy alto"
[19] "bajo" "medio" "muy alto" "alto" "muy alto" "muy alto"
[25] "medio" "bajo" "bajo" "bajo" "muy bajo" "muy alto"
Remover factores mediante paquete varhandle
unfactor(vector_fact_categorias) [1] "muy alto" "medio" "bajo" "alto" "muy alto" "bajo"
[7] "medio" "muy bajo" "alto" "muy alto" "muy alto" "bajo"
[13] "bajo" "muy bajo" "medio" "muy bajo" "muy bajo" "muy alto"
[19] "bajo" "medio" "muy alto" "alto" "muy alto" "muy alto"
[25] "medio" "bajo" "bajo" "bajo" "muy bajo" "muy alto"
Remover factores de paises_america2
as.character(levels(paises_america2))[paises_america2] [1] "Argentina" "Bolivia" "Brazil"
[4] "Canada" "Chile" "Colombia"
[7] "Costa Rica" "Cuba" "Dominican Republic"
[10] "Ecuador" "El Salvador" "Guatemala"
[13] "Haiti" "Honduras" "Jamaica"
[16] "Mexico" "Nicaragua" "Panama"
[19] "Paraguay" "Peru" "Puerto Rico"
[22] "Trinidad and Tobago" "United States" "Uruguay"
[25] "Venezuela"
Parte 3: Coerce
Coerción (coerce) en R se refiere al proceso automático de conversión de un tipo de dato a otro. Esto puede ocurrir cuando se realizan operaciones entre diferentes tipos de datos, y R intenta adaptar los datos para que puedan ser utilizados juntos.
Tipos de Coerción:
Coerción Implícita (Implicit Coercion): Ocurre automáticamente cuando realizas operaciones con diferentes tipos de datos.
Coerción Explícita (Explicit Coercion): Se realiza manualmente utilizando funciones específicas para convertir un tipo de dato a otro.
Coerción Implícita
Cuando intentas sumar un número entero y un número decimal, R convierte el número entero en un número decimal antes de realizar la operación.
# Coerción implícita: Suma de un número entero y un número decimal
entero <- 5L
decimal <- 3.2
resultado <- entero + decimal
resultado [1] 8.2
En este ejemplo, entero es un número entero (integer) y decimal es un número decimal (numeric). Cuando se suman, R convierte el integer en numeric para que puedan ser sumados.
Coerción Explícita
Puedes convertir manualmente un tipo de dato a otro utilizando funciones como as.numeric(), as.character(), as.logical() y más.
# Coerción explícita: Convertir un carácter a un número decimal
numero_como_cadena <- "3.2"
numero_decimal <- as.numeric(numero_como_cadena)
numero_decimal # Salida: 3.2[1] 3.2
# Coerción explícita: Convertir un número entero a un carácter
entero <- 5L
cadena <- as.character(entero)
cadena # Salida: "5"[1] "5"
En el primer ejemplo, as.numeric() convierte la cadena "3.2" en un número decimal 3.2. En el segundo ejemplo, as.character() convierte el entero 5L en la cadena "5".
Coerción en Data Frames
Cuando se crea un data frame con columnas de diferentes tipos de datos, R intenta coercer las columnas al tipo común más amplio.
# Crear un data frame con diferentes tipos de datos
df <- data.frame(
edad = c(25L, 30L, 35L),
nombre = c("Juan", "Ana", "Carlos"),
altura = c(1.75, 1.68, 1.80)
)
df edad nombre altura
1 25 Juan 1.75
2 30 Ana 1.68
3 35 Carlos 1.80
En este ejemplo, edad es una columna de enteros (integer), nombre es una columna de caracteres (character), y altura es una columna numérica (numeric). R convierte todas las columnas a tipo character para que puedan estar en el mismo formato.
Parte 4: Recycle
El recycle es el proceso por el cual R repite los elementos de un vector más corto hasta que pueda combinarlo con otro vector más largo. Esto ocurre cuando intentas realizar una operación entre dos vectores y uno tiene menos elementos que el otro.
Ejemplo 1: Suma de Vectores
Supongamos que tienes dos vectores:
vector_corto <- c(1, 2)
vector_largo <- c(3, 4, 5, 6)Si intentas sumar estos vectores:
resultado <- vector_corto + vector_largoR reciclará vector_corto para que tenga la misma longitud que vector_largo. Es decir, R repite los elementos de vector_corto hasta que coincida con la longitud de vector_largo.
El proceso sería algo así:
vector_corto: 1, 2- Repetir: 1, 2, 1, 2
Luego, realiza la suma elemento por elemento:
resultado <- c(1+3, 2+4, 1+5, 2+6)
resultado[1] 4 6 6 8
Multiplicación de Vectores
Ahora, considera otro ejemplo con multiplicación:
vector_corto <- c(2, 3)
vector_largo <- c(5, 7, 9, 11)Si intentas multiplicar estos vectores:
resultado <- vector_corto * vector_largoR reciclará vector_corto:
vector_corto: 2, 3- Repetir: 2, 3, 2, 3
Luego, realiza la multiplicación elemento por elemento:
resultado <- c(2*5, 3*7, 2*9, 3*11)
resultado[1] 10 21 18 33
Asignación de Valores
El recycle también se aplica cuando asignas valores a un vector más largo que el valor que estás asignando.
Supongamos que tienes un vector:
vector_largo <- c(0, 0, 0, 0)Y quieres asignarle los valores de otro vector más corto:
vector_corto <- c(1, 2)
vector_largo[] <- vector_cortoR reciclará vector_corto para que tenga la misma longitud que vector_largo:
vector_corto: 1, 2- Repetir: 1, 2, 1, 2
El resultado será:
vector_largo[1] 1 2 1 2
Consideraciones Importantes
- Longitud Exacta: Si el vector más corto no se puede reciclar exactamente para coincidir con la longitud del vector más largo (es decir, si no es un múltiplo), R producirá una advertencia y repetirá los elementos hasta que termine el vector más largo.
vector_corto <- c(1, 2)
vector_largo <- c(3, 4, 5)
resultado <- vector_corto + vector_largoEsto producirá una advertencia:
Warning message:
longer object length is not a multiple of shorter object length
Y el resultado será:
resultado[1] 4 6 6
- Operaciones Lógicas: El recycle también se aplica en operaciones lógicas.
vector_corto <- c(TRUE, FALSE)
vector_largo <- c(1, 2, 3, 4)
resultado <- vector_corto & (vector_largo > 2)R reciclará vector_corto:
vector_corto: TRUE, FALSE- Repetir: TRUE, FALSE, TRUE, FALSE
Luego, realiza la operación lógica elemento por elemento:
resultado <- c(TRUE & (1 > 2), FALSE & (2 > 2), TRUE & (3 > 2), FALSE & (4 > 2))El resultado será:
resultado[1] FALSE FALSE TRUE FALSE
Reciclado en una Data Frame
El recycle también se aplica cuando asignas un valor de un vector de menor lenght junto a otros en la construcción de una data frame.
df_recycle <- data.frame(vector_corto = '1',
vector_largo = 1:5)
df_recycle vector_corto vector_largo
1 1 1
2 1 2
3 1 3
4 1 4
5 1 5
El recycle es una característica de R que facilita operaciones entre vectores de diferentes longitudes. Sin embargo, es importante tener en cuenta las advertencias y asegurarse de que el reciclado produzca los resultados esperados.
Parte 5: Trabajando con Valores Faltantes
Los valores NA (que representan datos faltantes) es una tarea común en análisis de datos utilizando R. A
¿Qué son los valores NA?
Los valores NA en R representan “Not Available” y se utilizan para indicar que un dato está faltante o desconocido. Estos valores pueden surgir por diversas razones, como errores de entrada de datos, fallos en las mediciones, etc.
1. Identificación de Valores NA
Primero, es importante saber cómo identificar los valores NA en tus conjuntos de datos. Puedes usar la función is.na() para esto.
Ejemplo:
# Crear un vector con algunos valores NA
datos <- c(1, 2, NA, 4, NA, 6)
datos[1] 1 2 NA 4 NA 6
# Identificar los valores NA
is.na(datos)[1] FALSE FALSE TRUE FALSE TRUE FALSE
Contar Valores NA
Para saber cuántos valores NA hay en un conjunto de datos, puedes usar la función sum() junto con is.na().
Ejemplo:
# Contar los valores NA en el vector 'datos'
sum(is.na(datos))[1] 2
Eliminar Valores NA
Si deseas eliminar las observaciones que contienen valores NA, puedes usar la función na.omit().
Ejemplo:
# Eliminar filas con valores NA en un data frame
df <- data.frame(a = c(1, 2, NA), b = c(4, NA, 6))
df_sin_na <- na.omit(df)
df_sin_na a b
1 1 4
Reemplazar Valores NA
A veces es útil reemplazar los valores NA con algún otro valor, como la media o mediana de la columna.
Ejemplo:
# Reemplazar valores NA con la media de la columna 'a'
df$a[is.na(df$a)] <- mean(df$a, na.rm = TRUE)
df a b
1 1.0 4
2 2.0 NA
3 1.5 6
Manejo de Valores NA en Operaciones
Cuando realizas operaciones matemáticas, los valores NA pueden propagarse. Para evitar esto, puedes usar el parámetro na.rm = TRUE.
Ejemplo:
# Calcular la media ignorando los valores NA
mean(df$a, na.rm = TRUE)[1] 1.5
Uso de la función complete.cases()
La función complete.cases() te permite seleccionar solo las filas que no contienen valores NA.
Ejemplo:
# Seleccionar filas sin valores NA
df_completos <- df[complete.cases(df), ]
df_completos a b
1 1.0 4
3 1.5 6
Funciones de Apoyo al trabajar con NA
- Identificación:
is.na() - Conteo:
sum(is.na()) - Eliminación:
na.omit() - Reemplazo:
[is.na(columna)] <- valor_reemplazo - Operaciones:
na.rm = TRUE - Selección de casos completos:
complete.cases()
Coerción de NA´s
Los NA conservan sus propiedas al ser sometidos a coerciones explícitas
as.numeric(c(1,NA))[1] 1 NA
as.character(c('Prop',NA))[1] "Prop" NA
as.character(c(1,NA))[1] "1" NA
Ejemplo: trabajando con NA´s
Ver script
Filtrado de NA’s
Parte 6: Formatos de Datos Long y Wide
Formato Ancho (Wide): En este formato, cada columna representa una variable diferente y cada fila representa un caso o observación, por ejemplo un lugar o un paciente. Tendrás múltiples variables de observación, que contienen el mismo tipo de datos, para cada tema. Estas observaciones pueden ser repetidas a lo largo del tiempo, o puede ser la observación de múltiples variables (o una mezcla de ambos). Para algunas aplicaciones, es preferible el formato “ancho”. Sin embargo, muchas de las funciones de
Rhan sido diseñadas para datos de formato “largo”.Para los humanos, el formato “ancho” es a menudo más intuitivo ya que podemos ver más de los datos en la pantalla debido a su forma. Sin embargo, el formato “largo” es más legible para las máquinas y está más cerca al formateo de las bases de datos. Las variables de ID en nuestras data frames son similares a los campos en una base de datos y las variables observadas son como los valores de la base de datos.
Formato Largo (Long): En este formato, todas las variables están en una sola columna, y cada fila representa una combinación única de caso y variable. El formato “largo” es donde:
cada columna es una variable
cada fila es una observación
En el formato “largo”, generalmente tienes una columna para la variable observada y las otras columnas son variables de ID.
Explicación Gráfica:
Formatos Wide y Long
Proceso de Conversión de Wide a Long
pivot_longer(cols = starts_with("a"),
names_to = "key",
values_to = "value")
Material complementario: en la página https://swcarpentry.github.io/r-novice-gapminder-es/14-tidyr.html hay informaciones complementarias sobre estos formatos.
De dplyr a tidyr
Para trabajar con estas estructuras de datos y poder convertirlas de un formato long a widder o viceversa, es necesario incorporar en nuestra caja de herramientas el paquete tidyr que también se encuentra incluido en la suite tidyverse.
Creando Tibbles
Primero, vamos a crear algunos ejemplos de tibbles en R utilizando el paquete dplyr y tidyverse.
library(tidyverse)
# Crear un tibble ancho (wide)
datos_ancho <- tribble(
~nombre, ~edad_2015, ~edad_2016, ~edad_2017,
"Juan", 20, 21, 22,
"Ana", 23, 24, 25
)
datos_ancho# A tibble: 2 × 4
nombre edad_2015 edad_2016 edad_2017
<chr> <dbl> <dbl> <dbl>
1 Juan 20 21 22
2 Ana 23 24 25
# Crear un tibble largo (long)
datos_largo <- tribble(
~nombre, ~año, ~edad,
"Juan", 2015, 20,
"Juan", 2016, 21,
"Juan", 2017, 22,
"Ana", 2015, 23,
"Ana", 2016, 24,
"Ana", 2017, 25
)
datos_largo# A tibble: 6 × 3
nombre año edad
<chr> <dbl> <dbl>
1 Juan 2015 20
2 Juan 2016 21
3 Juan 2017 22
4 Ana 2015 23
5 Ana 2016 24
6 Ana 2017 25
Cambiando de Wide a Long
Para transformar un tibble ancho en largo, se utiliza la función pivot_longer() del paquete tidyr.
# Convertir datos_ancho a datos_largo
datos_largo <- datos_ancho %>%
pivot_longer(cols = starts_with("edad"),
names_to = "año",
values_to = "edad")
datos_largo# A tibble: 6 × 3
nombre año edad
<chr> <chr> <dbl>
1 Juan edad_2015 20
2 Juan edad_2016 21
3 Juan edad_2017 22
4 Ana edad_2015 23
5 Ana edad_2016 24
6 Ana edad_2017 25
Cambiando de Long a Wide
Para transformar un tibble largo en ancho, se utiliza la función pivot_wider() del paquete tidyr.
# Convertir datos_largo a datos_ancho
datos_ancho <- datos_largo %>%
pivot_wider(names_from = año,
values_from = edad)
datos_ancho# A tibble: 2 × 4
nombre edad_2015 edad_2016 edad_2017
<chr> <dbl> <dbl> <dbl>
1 Juan 20 21 22
2 Ana 23 24 25
Explicación de las Funciones
- pivot_longer(): Esta función se utiliza para convertir un tibble ancho en largo. Los argumentos principales son:
cols: Especifica qué columnas se deben convertir a formato largo.names_to: Define el nombre de la nueva columna que contendrá los nombres originales de las columnas.values_to: Define el nombre de la nueva columna que contendrá los valores.
- pivot_wider(): Esta función se utiliza para convertir un tibble largo en ancho. Los argumentos principales son:
names_from: Especifica qué columna contiene los nombres de las nuevas columnas.values_from: Especifica qué columna contiene los valores que se asignarán a las nuevas columnas.
Ventajas y Uso
- Formato Ancho (Wide):
- Ventaja: Facilita visualizar y comparar múltiples variables en una sola tabla.
- Uso: Útil cuando se necesita comparar fácilmente distintos valores de la misma variable para diferentes casos.
- Formato Largo (Long):
- Ventaja: Permite realizar análisis estadísticos más complejos, como modelos de series temporales o análisís longitudinales.
- Uso: Útil cuando se necesita realizar operaciones que requieren agrupar datos por una variable y luego aplicar funciones a los valores correspondientes.
Ejemplo Práctico
Supongamos que tienes un conjunto de datos sobre las ventas de diferentes productos en varios meses. Quieres analizar cómo ha evolucionado la venta de cada producto a lo largo del tiempo.
# Datos ancho (ejemplo)
ventas_ancho <- tribble(
~producto, ~enero, ~febrero, ~marzo,
"A", 100, 200, 150,
"B", 120, 220, 180
)
ventas_ancho# A tibble: 2 × 4
producto enero febrero marzo
<chr> <dbl> <dbl> <dbl>
1 A 100 200 150
2 B 120 220 180
# Convertir a formato largo
ventas_largo <- ventas_ancho %>%
pivot_longer(cols = starts_with("enero"),
names_to = "mes",
values_to = "venta")
ventas_largo# A tibble: 2 × 5
producto febrero marzo mes venta
<chr> <dbl> <dbl> <chr> <dbl>
1 A 200 150 enero 100
2 B 220 180 enero 120
Con el tibble en formato largo, puedes fácilmente calcular la tendencia de las ventas para cada producto utilizando funciones como group_by() y summarize().
# Calcular promedio de ventas por producto
promedio_ventas <- ventas_largo %>%
group_by(producto) %>%
summarize(promedio = mean(venta))
promedio_ventas# A tibble: 2 × 2
producto promedio
<chr> <dbl>
1 A 100
2 B 120
Ejercicios Pivots Longer:
Simulación de Precios de Accciones
En formato wider esta sería la df:
precio_acciones <- tibble(
fecha = as.Date("2024-01-01") + 0:9,
precio_x = rnorm(10, 0, 1),
precio_y = rnorm(10, 0, 2),
precio_z = rnorm(10, 0, 4)
)
precio_acciones# A tibble: 10 × 4
fecha precio_x precio_y precio_z
<date> <dbl> <dbl> <dbl>
1 2024-01-01 -1.08 -0.134 -0.860
2 2024-01-02 -0.851 2.27 -4.98
3 2024-01-03 0.0501 -0.564 6.76
4 2024-01-04 -1.56 0.835 -0.723
5 2024-01-05 0.627 0.853 -1.69
6 2024-01-06 0.680 -0.617 3.41
7 2024-01-07 -0.000215 0.856 -5.13
8 2024-01-08 -0.773 -2.10 -4.20
9 2024-01-09 0.239 -1.78 5.20
10 2024-01-10 1.71 -2.01 -3.37
Anteriormente en tidyr la función usada para convertir los datos a formanto longer era gather
# versión anterior con gather
precio_acciones %>%
gather("accion_nombe",
"precio_accion",
-fecha)# A tibble: 30 × 3
fecha accion_nombe precio_accion
<date> <chr> <dbl>
1 2024-01-01 precio_x -1.08
2 2024-01-02 precio_x -0.851
3 2024-01-03 precio_x 0.0501
4 2024-01-04 precio_x -1.56
5 2024-01-05 precio_x 0.627
6 2024-01-06 precio_x 0.680
7 2024-01-07 precio_x -0.000215
8 2024-01-08 precio_x -0.773
9 2024-01-09 precio_x 0.239
10 2024-01-10 precio_x 1.71
# ℹ 20 more rows
Precios de acciones en formato longer mediante el uso de pivot_longer
precio_acciones %>%
pivot_longer(cols = starts_with("precio"),
names_to = "accion_nombre",
values_to = "precio_accion")%>%
print(n=23)# A tibble: 30 × 3
fecha accion_nombre precio_accion
<date> <chr> <dbl>
1 2024-01-01 precio_x -1.08
2 2024-01-01 precio_y -0.134
3 2024-01-01 precio_z -0.860
4 2024-01-02 precio_x -0.851
5 2024-01-02 precio_y 2.27
6 2024-01-02 precio_z -4.98
7 2024-01-03 precio_x 0.0501
8 2024-01-03 precio_y -0.564
9 2024-01-03 precio_z 6.76
10 2024-01-04 precio_x -1.56
11 2024-01-04 precio_y 0.835
12 2024-01-04 precio_z -0.723
13 2024-01-05 precio_x 0.627
14 2024-01-05 precio_y 0.853
15 2024-01-05 precio_z -1.69
16 2024-01-06 precio_x 0.680
17 2024-01-06 precio_y -0.617
18 2024-01-06 precio_z 3.41
19 2024-01-07 precio_x -0.000215
20 2024-01-07 precio_y 0.856
21 2024-01-07 precio_z -5.13
22 2024-01-08 precio_x -0.773
23 2024-01-08 precio_y -2.10
# ℹ 7 more rows
Ingresos Anuales según Religión o Creencia Practicada:
Información basada en una encuesta sobre religión/creencia e ingresos obtenidos
head(relig_income)# A tibble: 6 × 11
religion `<$10k` `$10-20k` `$20-30k` `$30-40k` `$40-50k` `$50-75k` `$75-100k`
<chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 Agnostic 27 34 60 81 76 137 122
2 Atheist 12 27 37 52 35 70 73
3 Buddhist 27 21 30 34 33 58 62
4 Catholic 418 617 732 670 638 1116 949
5 Don’t kn… 15 14 15 11 10 35 21
6 Evangeli… 575 869 1064 982 881 1486 949
# ℹ 3 more variables: `$100-150k` <dbl>, `>150k` <dbl>,
# `Don't know/refused` <dbl>
relig_income %>%
pivot_longer(cols =!religion,
names_to = "income",
values_to = "count")# A tibble: 180 × 3
religion income count
<chr> <chr> <dbl>
1 Agnostic <$10k 27
2 Agnostic $10-20k 34
3 Agnostic $20-30k 60
4 Agnostic $30-40k 81
5 Agnostic $40-50k 76
6 Agnostic $50-75k 137
7 Agnostic $75-100k 122
8 Agnostic $100-150k 109
9 Agnostic >150k 84
10 Agnostic Don't know/refused 96
# ℹ 170 more rows
Cartelera de Éxitos Billoard:
head(billboard)# A tibble: 6 × 79
artist track date.entered wk1 wk2 wk3 wk4 wk5 wk6 wk7 wk8
<chr> <chr> <date> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 2 Pac Baby… 2000-02-26 87 82 72 77 87 94 99 NA
2 2Ge+her The … 2000-09-02 91 87 92 NA NA NA NA NA
3 3 Doors Do… Kryp… 2000-04-08 81 70 68 67 66 57 54 53
4 3 Doors Do… Loser 2000-10-21 76 76 72 69 67 65 55 59
5 504 Boyz Wobb… 2000-04-15 57 34 25 17 17 31 36 49
6 98^0 Give… 2000-08-19 51 39 34 26 26 19 2 2
# ℹ 68 more variables: wk9 <dbl>, wk10 <dbl>, wk11 <dbl>, wk12 <dbl>,
# wk13 <dbl>, wk14 <dbl>, wk15 <dbl>, wk16 <dbl>, wk17 <dbl>, wk18 <dbl>,
# wk19 <dbl>, wk20 <dbl>, wk21 <dbl>, wk22 <dbl>, wk23 <dbl>, wk24 <dbl>,
# wk25 <dbl>, wk26 <dbl>, wk27 <dbl>, wk28 <dbl>, wk29 <dbl>, wk30 <dbl>,
# wk31 <dbl>, wk32 <dbl>, wk33 <dbl>, wk34 <dbl>, wk35 <dbl>, wk36 <dbl>,
# wk37 <dbl>, wk38 <dbl>, wk39 <dbl>, wk40 <dbl>, wk41 <dbl>, wk42 <dbl>,
# wk43 <dbl>, wk44 <dbl>, wk45 <dbl>, wk46 <dbl>, wk47 <dbl>, wk48 <dbl>, …
dim(billboard)[1] 317 79
billboard %>%
pivot_longer(
cols = starts_with("wk"),
names_to = "week",
# names_prefix = "wk",
values_to = "rank",
values_drop_na = TRUE
)# A tibble: 5,307 × 5
artist track date.entered week rank
<chr> <chr> <date> <chr> <dbl>
1 2 Pac Baby Don't Cry (Keep... 2000-02-26 wk1 87
2 2 Pac Baby Don't Cry (Keep... 2000-02-26 wk2 82
3 2 Pac Baby Don't Cry (Keep... 2000-02-26 wk3 72
4 2 Pac Baby Don't Cry (Keep... 2000-02-26 wk4 77
5 2 Pac Baby Don't Cry (Keep... 2000-02-26 wk5 87
6 2 Pac Baby Don't Cry (Keep... 2000-02-26 wk6 94
7 2 Pac Baby Don't Cry (Keep... 2000-02-26 wk7 99
8 2Ge+her The Hardest Part Of ... 2000-09-02 wk1 91
9 2Ge+her The Hardest Part Of ... 2000-09-02 wk2 87
10 2Ge+her The Hardest Part Of ... 2000-09-02 wk3 92
# ℹ 5,297 more rows
Añadir prefijo a remover en la columna de destino
billboard %>%
pivot_longer(
cols = starts_with("wk"),
names_to = "week",
names_prefix = "wk",
values_to = "rank",
values_drop_na = TRUE
)# A tibble: 5,307 × 5
artist track date.entered week rank
<chr> <chr> <date> <chr> <dbl>
1 2 Pac Baby Don't Cry (Keep... 2000-02-26 1 87
2 2 Pac Baby Don't Cry (Keep... 2000-02-26 2 82
3 2 Pac Baby Don't Cry (Keep... 2000-02-26 3 72
4 2 Pac Baby Don't Cry (Keep... 2000-02-26 4 77
5 2 Pac Baby Don't Cry (Keep... 2000-02-26 5 87
6 2 Pac Baby Don't Cry (Keep... 2000-02-26 6 94
7 2 Pac Baby Don't Cry (Keep... 2000-02-26 7 99
8 2Ge+her The Hardest Part Of ... 2000-09-02 1 91
9 2Ge+her The Hardest Part Of ... 2000-09-02 2 87
10 2Ge+her The Hardest Part Of ... 2000-09-02 3 92
# ℹ 5,297 more rows
Informe Mundial Tuberculosis:
Un subconjunto de datos del Informe Mundial sobre la Tuberculosis de la Organización Mundial de la Salud. que utiliza los códigos originales de la Organización Mundial de la Salud.
Inspección Datos Entrada
names(who) [1] "country" "iso2" "iso3" "year" "new_sp_m014"
[6] "new_sp_m1524" "new_sp_m2534" "new_sp_m3544" "new_sp_m4554" "new_sp_m5564"
[11] "new_sp_m65" "new_sp_f014" "new_sp_f1524" "new_sp_f2534" "new_sp_f3544"
[16] "new_sp_f4554" "new_sp_f5564" "new_sp_f65" "new_sn_m014" "new_sn_m1524"
[21] "new_sn_m2534" "new_sn_m3544" "new_sn_m4554" "new_sn_m5564" "new_sn_m65"
[26] "new_sn_f014" "new_sn_f1524" "new_sn_f2534" "new_sn_f3544" "new_sn_f4554"
[31] "new_sn_f5564" "new_sn_f65" "new_ep_m014" "new_ep_m1524" "new_ep_m2534"
[36] "new_ep_m3544" "new_ep_m4554" "new_ep_m5564" "new_ep_m65" "new_ep_f014"
[41] "new_ep_f1524" "new_ep_f2534" "new_ep_f3544" "new_ep_f4554" "new_ep_f5564"
[46] "new_ep_f65" "newrel_m014" "newrel_m1524" "newrel_m2534" "newrel_m3544"
[51] "newrel_m4554" "newrel_m5564" "newrel_m65" "newrel_f014" "newrel_f1524"
[56] "newrel_f2534" "newrel_f3544" "newrel_f4554" "newrel_f5564" "newrel_f65"
dim(who)[1] 7240 60
head(who[,1:10])# A tibble: 6 × 10
country iso2 iso3 year new_sp_m014 new_sp_m1524 new_sp_m2534 new_sp_m3544
<chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
1 Afghanis… AF AFG 1980 NA NA NA NA
2 Afghanis… AF AFG 1981 NA NA NA NA
3 Afghanis… AF AFG 1982 NA NA NA NA
4 Afghanis… AF AFG 1983 NA NA NA NA
5 Afghanis… AF AFG 1984 NA NA NA NA
6 Afghanis… AF AFG 1985 NA NA NA NA
# ℹ 2 more variables: new_sp_m4554 <dbl>, new_sp_m5564 <dbl>
Convertir a formato longer
who %>%
pivot_longer(
cols = new_sp_m014:newrel_f65,
names_to = c("diagnosis", "gender", "age"),
names_pattern = "new_?(.*)_(.)(.*)",
values_to = "count"
)# A tibble: 405,440 × 8
country iso2 iso3 year diagnosis gender age count
<chr> <chr> <chr> <dbl> <chr> <chr> <chr> <dbl>
1 Afghanistan AF AFG 1980 sp m 014 NA
2 Afghanistan AF AFG 1980 sp m 1524 NA
3 Afghanistan AF AFG 1980 sp m 2534 NA
4 Afghanistan AF AFG 1980 sp m 3544 NA
5 Afghanistan AF AFG 1980 sp m 4554 NA
6 Afghanistan AF AFG 1980 sp m 5564 NA
7 Afghanistan AF AFG 1980 sp m 65 NA
8 Afghanistan AF AFG 1980 sp f 014 NA
9 Afghanistan AF AFG 1980 sp f 1524 NA
10 Afghanistan AF AFG 1980 sp f 2534 NA
# ℹ 405,430 more rows
Análisis patrón usado en names_pattern
library(stringr) # ya está cargada en tidyverse
str_split("new_sp_m2534", "new_?(.*)_(.)(.*)")[[1]]
[1] "" ""
# Hacer consultar a LLM sobre este patrón
cadena <- "new_user_123"
patron <- "new_?(.*)_(.)(.*)"
resultados <- str_match(cadena, patron)
resultados [,1] [,2] [,3] [,4]
[1,] "new_user_123" "user" "1" "23"
Ejercicios Pivots Widder:
Peces en Ríos
Información sobre los peces que nadan por un río: cada estación representa un monitor autónomo que registra si un pez marcado ha sido visto en ese lugar.
######## pivot_wider()
head(fish_encounters, 8)# A tibble: 8 × 3
fish station seen
<fct> <fct> <int>
1 4842 Release 1
2 4842 I80_1 1
3 4842 Lisbon 1
4 4842 Rstr 1
5 4842 Base_TD 1
6 4842 BCE 1
7 4842 BCW 1
8 4842 BCE2 1
fish_encounters %>%
pivot_wider(names_from = station,
values_from = seen)# A tibble: 19 × 12
fish Release I80_1 Lisbon Rstr Base_TD BCE BCW BCE2 BCW2 MAE MAW
<fct> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>
1 4842 1 1 1 1 1 1 1 1 1 1 1
2 4843 1 1 1 1 1 1 1 1 1 1 1
3 4844 1 1 1 1 1 1 1 1 1 1 1
4 4845 1 1 1 1 1 NA NA NA NA NA NA
5 4847 1 1 1 NA NA NA NA NA NA NA NA
6 4848 1 1 1 1 NA NA NA NA NA NA NA
7 4849 1 1 NA NA NA NA NA NA NA NA NA
8 4850 1 1 NA 1 1 1 1 NA NA NA NA
9 4851 1 1 NA NA NA NA NA NA NA NA NA
10 4854 1 1 NA NA NA NA NA NA NA NA NA
11 4855 1 1 1 1 1 NA NA NA NA NA NA
12 4857 1 1 1 1 1 1 1 1 1 NA NA
13 4858 1 1 1 1 1 1 1 1 1 1 1
14 4859 1 1 1 1 1 NA NA NA NA NA NA
15 4861 1 1 1 1 1 1 1 1 1 1 1
16 4862 1 1 1 1 1 1 1 1 1 NA NA
17 4863 1 1 NA NA NA NA NA NA NA NA NA
18 4864 1 1 NA NA NA NA NA NA NA NA NA
19 4865 1 1 1 NA NA NA NA NA NA NA NA
Análisis Gapminder
¿Cuál estructura (longer o widder) tiene el conjunto de datos Gapminder?
head(df_gapminder_csv)# A tibble: 6 × 6
country continent year lifeExp pop gdpPercap
<chr> <chr> <int> <dbl> <int> <dbl>
1 Afghanistan Asia 1952 28.8 8425333 779.
2 Afghanistan Asia 1957 30.3 9240934 821.
3 Afghanistan Asia 1962 32.0 10267083 853.
4 Afghanistan Asia 1967 34.0 11537966 836.
5 Afghanistan Asia 1972 36.1 13079460 740.
6 Afghanistan Asia 1977 38.4 14880372 786.
Consideraciones Finales
Entender los formatos de datos long y wide es crucial para trabajar eficazmente con datos en R. Dependiendo del análisis que quieras realizar, uno de estos formatos puede ser más apropiado que el otro. Afortunadamente, las funciones pivot_longer() y pivot_wider() facilitan la transición entre ambos formatos.